#include "stdafx.h"
#include "console.h"

extern "C"
{

LPBYTE pConBuff = (LPBYTE)0x0b8000;

#define ROWS 25
#define COLS 80
#define BUFF_SZ ROWS * COLS * 2

WORD position = 0;
BYTE color = 0xf0;

WORD __vga_port;

void putc_ex(LPVOID, char c)
{
	putch(c);
}

void init_console()
{
	SetBGColor(0);
	SetFGColor(7);

	init_printf(NULL, putc_ex);
	
	cls();

	position = 0;
}


// 0 = Black	8 = Gray
// 1 = Blue	9 = Light Blue
// 2 = Green	A = Light Green
// 3 = Aqua	B = Light Aqua
// 4 = Red	C = Light Red
// 5 = Purple	D = Light Purple
// 6 = Yellow	E = Light Yellow
// 7 = White	F = Bright White

void SetFGColor(BYTE c)
{
	color = (color & 0xf0) | (c & 0x0f);
}

void SetBGColor(BYTE c)
{
	color = (color & 0x0f) | (c << 4);
}

void cls()
{
	position = 0;

	for (int i = 0; i < ROWS; i++)
	{
		ClearCurrentRow();

		position += COLS;
	}

	position = 0;
}

#define WRITE_DISP_PORT_CMD(value)	outb(*(WORD*)0x0463, value)
#define WRITE_DISP_PORT_DATA(value)	outb(1 + *(WORD*)0x0463, value)


void ClearCurrentRow()
{
	position = COLS * (position / COLS);

	WORD row = position;

	for (int i = 0; i < COLS; i++)
	{
		putch(' ');
	}

	position = row;
}


void putch(char c)
{
	LPBYTE pBuff = (LPBYTE)((position * 2) + pConBuff);

	if (c == '\n')
	{
		position += COLS;
	}
	else if (c == '\r')
	{
		position -= position % COLS;
	}
	else if (c == '\t')
	{
		int c = 4 - (position % COLS) % 4;
		for (int i = 0; i < c; i++)
		{
			putch(' ');
		}
	}
	else
	{
		pBuff[0] = c < ' ' ? ' ' : c;
		pBuff[1] = color;

		position++;
	}
}

void puts(char* c)
{
	if (c)
	{
		while (*c)
		{
			putch(*c);

			c++;
		}
	}
}

void putline(char* c /* = NULL */)
{
	puts(c);

	WORD offs = position % COLS;
	if (offs != 0)
	{
		position += COLS - offs;
	}
}

}